package org.papillion39.sechelper.application.business;

import java.util.LinkedList;

import org.papillion39.sechelper.application.business.model.Recipient;
import java.util.List;

import javax.annotation.Resource;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.SetJoin;

import org.papillion39.sechelper.application.data.model.Person;
import org.papillion39.sechelper.application.data.model.PersonAddress;
import org.papillion39.sechelper.application.data.model.PersonAddress_;
import org.papillion39.sechelper.application.data.model.Person_;

/**
 *
 * @author Jonathan Paz <jonathan.paz@ottr.com>
 */
@Stateless
@DeclareRoles({"user","secretary","distributor","admin"})
@RolesAllowed({"secretary","distributor"})
public class DistributionList implements DistributionListLocal {
    @PersistenceContext
    private EntityManager em;

    @Resource
    private javax.transaction.UserTransaction utx;

    @Override
    public List<Recipient> emailDistributionList() {
        LinkedList<Recipient> recipients = new LinkedList<>();
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Person> cq = cb.createQuery(Person.class);
        Root<Person> root = cq.from(Person.class);
        cq.select(root).where(cb.isTrue(root.get(Person_.preferEmail)));
        TypedQuery<Person> q = em.createQuery(cq);
        List<Person> persons = q.getResultList();
        persons.stream().forEach((p) -> {
            recipients.add(new Recipient(p.getFirstName(),p.getMiddleName(), p.getLastName(), p.getEmail(), null, null, null, null, null, null, true));
        });
        return recipients;
    }
    
    @Override
    public List<Recipient> postalDistributionList() {
        LinkedList<Recipient> recipients = new LinkedList<>();
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Tuple> cq = cb.createTupleQuery();
        Root<Person> person = cq.from(Person.class);
        SetJoin<Person,PersonAddress> address = person.join(Person_.personAddressSet);
        address.on(cb.isTrue(address.get(PersonAddress_.preferred)));
        cq.multiselect(person,address).where(cb.isFalse(person.get(Person_.preferEmail)));
        TypedQuery<Tuple> q = em.createQuery(cq);
        List<Tuple> tuples = q.getResultList();
        tuples.stream().forEach((tuple) -> {
            Person p = tuple.get(person);
            PersonAddress a = tuple.get(address);
            recipients.add(new Recipient(p.getFirstName(),
                    p.getMiddleName(),
                    p.getLastName(),
                    p.getEmail(),
                    a.getLine1(),
                    a.getLine2(),
                    a.getLine3(),
                    a.getCity(),
                    a.getStateProvince(),
                    a.getPostalCode(),
                    false));
        });
        return recipients;
    }
 
}
